import { Inject, Injectable, forwardRef } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Role } from "./entities/role.entity";
import { FindCondition, FindConditions, In, Like, Repository } from "typeorm";
import { ReqAddRoleDto, ReqSearchRoleDto } from "./dto/req-role.dto";
import { PaginatedDto } from "src/common/dto/paginated.dto";
import { MenuService } from "../menu/menu.service";
import { ApiException } from "src/common/exceptions/api.exception";

@Injectable()
export class RoleService {
  constructor(
    @InjectRepository(Role) private readonly roleRepository: Repository<Role>,
    @Inject(forwardRef(() => MenuService)) private readonly menuService: MenuService,
  ) {}

  // 分页查询
  async getRoleList(reqSearchRoleDto: ReqSearchRoleDto): Promise<PaginatedDto<Role>> {
    let where: FindConditions<Role> = {
      delFlag: "0",
    };
    if (reqSearchRoleDto.role_name) {
      where.role_name = Like(`%${reqSearchRoleDto.role_name}%`);
    }

    const result = await this.roleRepository.findAndCount({
      select: ["role_id", "role_name", "role_key"],
      where,
      skip: reqSearchRoleDto.skip,
      take: reqSearchRoleDto.take,
    });
    for (let i = 0; i < result[0].length; i++) {
      const item = result[0][i];
      item.menus = await this.menuService.getMenusByRoleId(item.role_id);
    }
    return {
      list: result[0],
      totalNum: result[1],
      pageNum: reqSearchRoleDto.pageNum,
      pageSize: reqSearchRoleDto.pageSize,
    };
  }

  // 新增/编辑角色
  async addOrUpdateRole(reqAddRoleDto: ReqAddRoleDto) {
    const menuArr = await this.menuService.listByIdArr(reqAddRoleDto.menu_ids);
    reqAddRoleDto.menus = menuArr;
    // console.log("reqAddRoleDto: ", reqAddRoleDto);
    await this.roleRepository.save(reqAddRoleDto);
  }

  // 通过角色名称或权限查询
  async getRoleByNameOrKey(role_name: string, role_key: string | number): Promise<Role[]> {
    const role = await this.roleRepository
      .createQueryBuilder("role")
      .select("role.role_id", "role_id")
      .addSelect("role.role_name", "role_name")
      .addSelect("role.role_key", "role_key")
      .where("role.role_name = :role_name", { role_name })
      .orWhere("role.role_key = :role_key", { role_key })
      .getRawMany();
    return role;
  }

  // 删除角色
  async deleteRoleById(role_id: string | number) {
    // 1.获取角色下是否有用户，如果有用户，不允许删除
    const count = await this.roleRepository
      .createQueryBuilder("role")
      .innerJoinAndSelect("role.users", "user")
      .where("role.role_id = :role_id", { role_id })
      .getCount();
    if (count > 0) {
      // 角色下有用户，不允许删除
      throw new ApiException("该角色下存在用户，不允许删除！");
    }
    return this.roleRepository.delete(role_id);
  }

  // 通过id数组查询
  async getRolesByIdArr(idArr: number[]) {
    return this.roleRepository.find({
      where: {
        delFlag: 0,
        role_id: In(idArr),
      },
    });
  }

  // 通过用户id查询角色信息
  async getRolesByUserId(userId: number | string) {
    return await this.roleRepository
      .createQueryBuilder("role")
      .innerJoin("role.users", "user")
      .select("role.role_id", "role_id")
      .addSelect("role.role_name", "role_name")
      .where("user.userId = :userId", { userId })
      .getRawMany();
  }
}
